/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.model.femModel;

import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Observable;
import java.util.Observer;

import br.ufmg.dees.insane.analysisModel.AnalysisModel;
import br.ufmg.dees.insane.continuousPointModel.ContinuousPointModel;
import br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel;
import br.ufmg.dees.insane.materialMedia.degeneration.Degeneration;
import br.ufmg.dees.insane.materialMedia.material.Material;
import br.ufmg.dees.insane.model.femModel.element.Element;
import br.ufmg.dees.insane.model.femModel.loads.Loading;
import br.ufmg.dees.insane.model.femModel.node.Node;
import br.ufmg.dees.insane.model.femModel.problemDriver.ProblemDriver;
import br.ufmg.dees.insane.shape.Shape;
import br.ufmg.dees.insane.util.LoadCombination;
import br.ufmg.dees.insane.util.numericalIntegration.IntegrationOrder;


/**
*A class representing a FEM model.
*
*@author Camara,Luciana & Pitangueira, Roque
*@version 1.0
*@since Maio 2005
*@see Node
*@see Element
*@see IntegrationOrder
*@see AnalysisModel
*@see ContinuousPointModel
*@see Shape
*@see Degeneration
*@see ProblemDriver 
*@see MaterialMedia
**/

public class FemModel extends Observable implements java.io.Serializable, Model {
	
	/**
	 * Comment for <code>serialVersionUID</code>
	 */
	private static final long serialVersionUID = 1L;

	/** This FemModel's Nodes list. */
	protected ArrayList<Node> nodes = new ArrayList<Node>();
	
	/** This FemModel's Elements list. */
	protected ArrayList<Element> elements = new ArrayList<Element>();
	
	/** This FemModel's AnalysisModel list. */
	protected ArrayList<AnalysisModel> analysisModels = new ArrayList<AnalysisModel>();
	
	/** This FemModel's ContinuousPointModel list. */
	protected ArrayList<ContinuousPointModel> continuousPointModels = new ArrayList<ContinuousPointModel>();
	
	/** This FemModel's Shapes list. */
	protected ArrayList<Shape> shapes = new ArrayList<Shape>();
	
	/** This FemModel's IntegrationOrder list. */
	protected ArrayList<IntegrationOrder> integrationOrders = new ArrayList<IntegrationOrder>();
    
    /** This FemModel's loadCombination list. */
    protected ArrayList<LoadCombination> loadCombinations = new ArrayList<LoadCombination>();
    
//    /** This FemModel's loadCases list. */
//    protected ArrayList<LoadCase> loadCases = new ArrayList<LoadCase>();
    
    /** This FemModel's loading list. */
    protected ArrayList<Loading> loadings = new ArrayList<Loading>();
	
	/** This FemModel's ProblemDriver. */
	protected ProblemDriver probDriver;
	
	/** This FemModel's global AnalysisModel. */
	protected AnalysisModel globalAnalysisModel;
	
	/** This FemModel's Degeneration list.*/
	protected ArrayList<Degeneration> degenerations = new ArrayList<Degeneration>();
	
	/** This FemModel's Materials list.*/
	protected ArrayList<Material> materials = new ArrayList<Material>();
	
	/** This FemModel's ConstitutiveModel list.*/
	protected ArrayList<ConstitutiveModel> constitutiveModels = new ArrayList<ConstitutiveModel>();
	
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#getNumberOfLoadCombinations()
     */
    public int getNumberOfLoadCombinations(){
        return (loadCombinations.size());
    };
   
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#getLoadCombinationsList()
     */
    public ArrayList<LoadCombination> getLoadCombinationsList(){
        return (loadCombinations);
    };
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#getLoadCombination(java.lang.String)
     */
    public LoadCombination getLoadCombination(String a) {
        LoadCombination lc;
        ListIterator lcs = loadCombinations.listIterator();
        while (lcs.hasNext()) {
            lc = (LoadCombination) lcs.next();
            if (lc.getLabel().equals(a)) {
                return (lc);
            };
        };
        return (null);
    };
    
   
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.util.LoadCombination)
     */
    public void add(LoadCombination a) {
        loadCombinations.add(a);
    };
   
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#remove(br.ufmg.dees.insane.util.LoadCombination)
     */
    public void remove(LoadCombination a) {
        LoadCombination lc;
        ListIterator lcs = loadCombinations.listIterator();
        while (lcs.hasNext()) {
            lc = (LoadCombination) lcs.next();
            if (lc.getLabel().equals(a.getLabel())) {
                loadCombinations.remove(lc);
            };
        };
    };
    
//    /* (non-Javadoc)
//     * @see br.ufmg.dees.insane.model.femModel.Model#getNumberOfLoadCombinations()
//     */
//    public int getNumberOfLoadCases(){
//        return (loadCases.size());
//    };
//   
//    /* (non-Javadoc)
//     * @see br.ufmg.dees.insane.model.femModel.Model#getLoadCombinationsList()
//     */
//    public ArrayList getLoadCasesList(){
//        return (loadCases);
//    };
//    
//    /* (non-Javadoc)
//     * @see br.ufmg.dees.insane.model.femModel.Model#getLoadCombination(java.lang.String)
//     */
//    public LoadCase getLoadCase(String a) {
//        LoadCase lc;
//        ListIterator lcs = loadCases.listIterator();
//        while (lcs.hasNext()) {
//            lc = (LoadCase) lcs.next();
//            if (lc.getLabel().equals(a)) {
//                return (lc);
//            };
//        };
//        return (null);
//    };
//    
//   
//    /* (non-Javadoc)
//     * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.util.LoadCombination)
//     */
//    public void add(LoadCase a) {
//        if (loadCases.isEmpty()) {
//            loadCases.add(a);
//            return;
//        }
//        else {
//        LoadCase lc;
//        ListIterator lcs = loadCases.listIterator();
//        while (lcs.hasNext()) {
//            lc = (LoadCase) lcs.next();
//            if (!lc.getLabel().equals(a.getLabel())) {
//                loadCases.add(a);
//                return;
//            };
//        };
//        }
//    };
//   
//    /* (non-Javadoc)
//     * @see br.ufmg.dees.insane.model.femModel.Model#remove(br.ufmg.dees.insane.util.LoadCombination)
//     */
//    public void remove(LoadCase a) {
//        LoadCase lc;
//        ListIterator lcs = loadCases.listIterator();
//        while (lcs.hasNext()) {
//            lc = (LoadCase) lcs.next();
//            if (lc.getLabel().equals(a.getLabel())) {
//                loadCases.remove(lc);
//            };
//        };
//    };
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#getNumberOfLoading()
     */
    public int getNumberOfLoading(){
        return (loadings.size());
    };
   
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#getLoadingList()
     */
    public ArrayList<Loading> getLoadingList(){
        return (loadings);
    };
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#getLoading(java.lang.String)
     */
    public Loading getLoading(String a) {
    	Loading loading;
        ListIterator lcs = loadings.listIterator();
        while (lcs.hasNext()) {
        	loading = (Loading) lcs.next();
            if (loading.getLabel().equals(a)) {
                return (loading);
            };
        };
        return (null);
    };
   
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.model.femModel.loads.Loading)
     */
    public void add(Loading a) {
        if (loadings.isEmpty()) {
        	loadings.add(a);
            return;
        }
        else {
        Loading lc;
        ListIterator lcs = loadings.listIterator();
        while (lcs.hasNext()) {
            lc = (Loading) lcs.next();
            if (!lc.getLabel().equals(a.getLabel())) {
            	loadings.add(a);
                return;
            };
        };
        }
    };
   
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#remove(br.ufmg.dees.insane.model.femModel.loads.Loading)
     */
    public void remove(Loading a) {
    	Loading lc;
        ListIterator lcs = loadings.listIterator();
        while (lcs.hasNext()) {
            lc = (Loading) lcs.next();
            if (lc.getLabel().equals(a.getLabel())) {
            	loadings.remove(lc);
            };
        };
    };

    /* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNumberOfElements()
	 */
	public int getNumberOfElements(){
		return (elements.size());
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getElementsList()
	 */
	public ArrayList<Element> getElementsList(){
		return (elements);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getElement(java.lang.String)
	 */
	public Element getElement(String a) {
		Element elm;
		ListIterator elms = elements.listIterator();
		while (elms.hasNext()) {
			elm = (Element) elms.next();
			if (elm.getLabel().equals(a)) {
				return (elm);
			};
		};
		return (null);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.model.femModel.element.Element)
	 */
	public void add(Element a) {
		elements.add(a);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#remove(br.ufmg.dees.insane.model.femModel.element.Element)
	 */
	public void remove(Element a) {
		Element elm;
		ListIterator elms = elements.listIterator();
		while (elms.hasNext()) {
			elm = (Element) elms.next();
			if (elm.getLabel().equals(a.getLabel())) {
				elements.remove(elm);
			};
		};
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNumberOfNodes()
	 */
	public int getNumberOfNodes(){
		return (nodes.size());
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNodesList()
	 */
	public ArrayList<Node> getNodesList(){
		return (nodes);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNode(java.lang.String)
	 */
	public Node getNode(String a) {
		Node node;
		ListIterator nds = nodes.listIterator();
		while (nds.hasNext()) {
			node = (Node) nds.next();
			if (node.getLabel().equals(a)) {
				return (node);
			};
		};
		return (null);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNode(double, double)
	 */
	public Node getNode(double x, double y) {
		Node node;
		ListIterator nds = nodes.listIterator();
		while (nds.hasNext()) {
			node = (Node) nds.next();
			if (node.getPoint().x == x && node.getPoint().y == y && node.getPoint().z == 0) {
				return (node);
			};
		};
		return (null);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNode(double, double, double)
	 */
	public Node getNode(double x, double y, double z) {
		Node node;
		ListIterator nds = nodes.listIterator();
		while (nds.hasNext()) {
			node = (Node) nds.next();
			if (node.getPoint().x == x && node.getPoint().y == y && node.getPoint().z == z) {
				return (node);
			};
		};
		return (null);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.model.femModel.node.Node)
	 */
	public void add(Node a) {
		nodes.add(a);
	};
	
	public void remove(Node a) {
		Node node;
		ListIterator nds = nodes.listIterator();
		while (nds.hasNext()) {
			node = (Node) nds.next();
			if (node.getLabel().equals(a.getLabel())) {
				nodes.remove(node);
			};
		};
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNumberOfAnalysisModels()
	 */
	public int getNumberOfAnalysisModels(){
		return (analysisModels.size());
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNumberOfContinuousPointModels()
	 */
	public int getNumberOfContinuousPointModels(){
		return (continuousPointModels.size());
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getAnalysisModelsList()
	 */
	public ArrayList<AnalysisModel> getAnalysisModelsList(){
		return (analysisModels);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getContinuousPointModelsList()
	 */
	public ArrayList<ContinuousPointModel> getContinuousPointModelsList(){
		return (continuousPointModels);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getAnalysisModel(java.lang.String)
	 */
	public AnalysisModel getAnalysisModel(String a) {
		AnalysisModel am;
		ListIterator ams = analysisModels.listIterator();
		while (ams.hasNext()) {
			am = (AnalysisModel) ams.next();
			if (am.getLabel().equals(a)) {
				return (am);
			};
		};
		return (null);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getContinuousPointModel(java.lang.String)
	 */
	public ContinuousPointModel getContinuousPointModel(String a) {
		ContinuousPointModel am;
		ListIterator ams = continuousPointModels.listIterator();
		while (ams.hasNext()) {
			am = (ContinuousPointModel) ams.next();
			if (am.getLabel().equals(a)) {
				return (am);
			};
		};
		return (null);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.analysisModel.AnalysisModel)
	 */
	public void add(AnalysisModel a)
	{
		AnalysisModel anl;
		ListIterator anls = analysisModels.listIterator();
		
		if(!anls.hasNext())
			analysisModels.add(a);
		else
		{
			while (anls.hasNext())
			{
				anl = (AnalysisModel) anls.next();
				
				if (anl.getLabel().equals(a.getLabel()))return;
			}
			analysisModels.add(a);
		}
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.continuousPointModel.ContinuousPointModel)
	 */
	public void add(ContinuousPointModel a)
	{
		ContinuousPointModel anl;
		ListIterator anls = continuousPointModels.listIterator();
		
		if(!anls.hasNext())
			continuousPointModels.add(a);
		else
		{
			while (anls.hasNext())
			{
				anl = (ContinuousPointModel) anls.next();
				
				if (anl.getLabel().equals(a.getLabel()))return;
			}
			continuousPointModels.add(a);
		}
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#remove(br.ufmg.dees.insane.analysisModel.AnalysisModel)
	 */
	public void remove(AnalysisModel a) {
		AnalysisModel anl;
		ListIterator anls = analysisModels.listIterator();
		while (anls.hasNext()) {
			anl = (AnalysisModel) anls.next();
			if (anl.getLabel().equals(a.getLabel())) {
				analysisModels.remove(anl);
			};
		};
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#remove(br.ufmg.dees.insane.continuousPointModel.ContinuousPointModel)
	 */
	public void remove(ContinuousPointModel a) {
		ContinuousPointModel anl;
		ListIterator anls = continuousPointModels.listIterator();
		while (anls.hasNext()) {
			anl = (ContinuousPointModel) anls.next();
			if (anl.getLabel().equals(a.getLabel())) {
				continuousPointModels.remove(anl);
			};
		};
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNumberOfShapes()
	 */
	public int getNumberOfShapes(){
		return (shapes.size());
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getShape(java.lang.String)
	 */
	public Shape getShape(String a)
	{
		Shape shape;
		ListIterator shps = shapes.listIterator();
		while (shps.hasNext())
		{
			shape = (Shape) shps.next();
			if (shape.getType().equals(a))
			{
				return (shape);
			}
		}
		return (null);
	}
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getShapesList()
	 */
	public ArrayList<Shape> getShapesList(){
		return (shapes);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.shape.Shape)
	 */
	public void add(Shape a) {
		Shape shp;
		ListIterator shps = shapes.listIterator();
		
		if(!shps.hasNext())
			shapes.add(a);
		else
		{
			while (shps.hasNext())
			{
				shp = (Shape) shps.next();
				
				if (shp.getType().equals(a.getType()))return;
			}
			shapes.add(a);
		}
	};

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getNumberOfIntegrationOrders()
	 */
	public int getNumberOfIntegrationOrders(){
		return (integrationOrders.size());
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getIntegrationOrdersList()
	 */
	public ArrayList<IntegrationOrder> getIntegrationOrdersList()
	{
		return (integrationOrders);
	}
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.util.numericalIntegration.IntegrationOrder)
	 */
	public void add(IntegrationOrder a)
	{
		IntegrationOrder integrationOrder;
		ListIterator intOrds = integrationOrders.listIterator();
		
		if(!intOrds.hasNext())
			integrationOrders.add(a);
		else
		{
			while (intOrds.hasNext())
			{
				integrationOrder = (IntegrationOrder) intOrds.next();
				
				if (integrationOrder.getLabel().equals(a.getLabel()))return;
			}
			integrationOrders.add(a);
		}
	}
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getIntegrationOrder(java.lang.String)
	 */
	public IntegrationOrder getIntegrationOrder(String a)
	{
		IntegrationOrder integrationOrder;
		ListIterator intOrds = integrationOrders.listIterator();
		
		while (intOrds.hasNext())
		{
			integrationOrder = (IntegrationOrder) intOrds.next();
			if (integrationOrder.getLabel().equals(a))
			{
				return (integrationOrder);
			}
		}
		return (null);
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getGlobalAnalysisModel()
	 */
	/**
	 * @return  Returns the globalAnalysisModel.
	 * @uml.property  name="globalAnalysisModel"
	 */
	public AnalysisModel getGlobalAnalysisModel(){
		return (globalAnalysisModel);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#setGlobalAnalysisModel(br.ufmg.dees.insane.analysisModel.AnalysisModel)
	 */
	/**
	 * @param globalAnalysisModel  The globalAnalysisModel to set.
	 * @uml.property  name="globalAnalysisModel"
	 */
	public void setGlobalAnalysisModel(AnalysisModel a){
		globalAnalysisModel = a;
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getProblemDriver()
	 */
	public ProblemDriver getProblemDriver(){
		return (probDriver);
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#setProblemDriver(br.ufmg.dees.insane.model.femModel.problemDriver.ProblemDriver)
	 */
	public void setProblemDriver(ProblemDriver a){
	    probDriver = a;
	};
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getDegenerationsList()
	 */
	public ArrayList<Degeneration> getDegenerationsList() {
		return (degenerations);
	}
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.materialMedia.degeneration.Degeneration)
	 */
	public void add(Degeneration dg) {
		this.degenerations.add(dg);
	}
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getDegeneration(java.lang.String)
	 */
	public Degeneration getDegeneration(String label) {
	    ListIterator degenerations = this.getDegenerationsList().listIterator();
	    while (degenerations.hasNext()) {
		    Degeneration dg = (Degeneration) degenerations.next();
		    if (dg.getOriginalLabel().equals(label)) {
		        return dg;
		    }
		}
	    return null;
	}
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.materialMedia.constitutiveModel.ConstitutiveModel)
	 */
	public void add(ConstitutiveModel cm) {
		this.constitutiveModels.add(cm);
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#add(br.ufmg.dees.insane.materialMedia.material.Material)
	 */
	public void add(Material mat) {
		this.materials.add(mat);
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getConstitutiveModel(java.lang.String)
	 */
	public ConstitutiveModel getConstitutiveModel(String label) {
		ListIterator cms = this.getConstitutiveModelsList().listIterator();
	    while (cms.hasNext()) {
	    	ConstitutiveModel cm = (ConstitutiveModel) cms.next();
		    if (cm.getLabel().equals(label)) {
		        return cm;
		    }
		}
	    return null;
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getConstitutiveModelsList()
	 */
	public ArrayList<ConstitutiveModel> getConstitutiveModelsList() {
		return this.constitutiveModels;
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getMaterial(java.lang.String)
	 */
	public Material getMaterial(String label) {
		ListIterator mats = this.getMaterialsList().listIterator();
	    while (mats.hasNext()) {
	    	Material mat = (Material) mats.next();
		    if (mat.getLabel().equals(label)) {
		        return mat;
		    }
		}
	    return null;
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#getMaterialsList()
	 */
	public ArrayList<Material> getMaterialsList() {
		return this.materials;
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#clearAll()
	 */
	public void clearAll() {
		nodes.clear();
		elements.clear();
		analysisModels.clear();
		shapes.clear();
		integrationOrders.clear();
	}
	
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#cleanResults()
	 */
	public void cleanResults() {
		ListIterator i = nodes.listIterator();
		while (i.hasNext()) {
			Node no = (Node)i.next();
			no.cleanResults();
		}
	}
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.Model#update()
     */
    public void update() {
        this.setChanged();
        this.hasChanged();
        this.notifyObservers();
        ListIterator elements = this.getElementsList().listIterator();
        while (elements.hasNext()) {
            Element elm = (Element)elements.next();
            elm.update();
        } 
    }
    
    /* (non-Javadoc)
     * @see java.util.Observable#addObserver(java.util.Observer)
     */
    public synchronized void addObserver(Observer arg0) {
        super.addObserver(arg0);
    }
    
    /* (non-Javadoc)
     * @see java.util.Observable#deleteObserver(java.util.Observer)
     */
    public synchronized void deleteObserver(Observer arg0) {
        super.deleteObserver(arg0);
    }
    
    /* (non-Javadoc)
     * @see java.util.Observable#deleteObservers()
     */
    public synchronized void deleteObservers() {
        super.deleteObservers();
    }
    
    /* (non-Javadoc)
     * @see java.util.Observable#hasChanged()
     */
    public synchronized boolean hasChanged() {
        return super.hasChanged();
    }
    
    /* (non-Javadoc)
     * @see java.util.Observable#notifyObservers()
     */
    public void notifyObservers() {
        super.notifyObservers();
    }

    public ArrayList<String> getNodeKeys() {
    	ArrayList<String> keys = new ArrayList<String>();
    	for (int i = 0; i < this.analysisModels.size(); i++) {
			AnalysisModel anl = this.analysisModels.get(i);
    		for (int j = 0; j <anl.getDOFLabels().size(); j++) {
    			keys.add(this.probDriver.getStateVariableLabel()+"-"+anl.getDOFLabels().get(j));
    			keys.add(this.probDriver.getDualVariableLabel()+"-"+anl.getDOFLabels().get(j));
			}
		}
    	return keys;
    }
    
    public ArrayList<String> getElementKeys() {
    	ArrayList<String> keys = new ArrayList<String>();
    	for (int i = 0; i < this.analysisModels.size(); i++) {
    		AnalysisModel anl = this.analysisModels.get(i);
    		for (int j = 0; j <anl.getInternalVariablesLabels().length; j++) {
    			//keys.add(this.probDriver.getInternalVariableLabel()+"-"+anl.getInternalVariablesLabels()[j]);
    			keys.add(anl.getInternalVariablesLabels()[j]);
    		}
    		for (int j = 0; j <anl.getDualInternalVariablesLabels().length; j++) {
    			//keys.add(this.probDriver.getInternalDualVariableLabel()+"-"+anl.getDualInternalVariablesLabels()[j]);
    			keys.add(anl.getDualInternalVariablesLabels()[j]);
    		}
    	}
    	return keys;
    }
    
    /**
     * Inits the static varibles of the node, acording the Model Problem Driver 
     */
    public void initKeys(){
		Node.STATE_VARIABLE = this.getProblemDriver().getStateVariableLabel();
		Node.DUAL_VARIABLE = this.getProblemDriver().getDualVariableLabel();
		Node.PRE_STATE_VARIABLE = "PRE-"+this.getProblemDriver().getStateVariableLabel();
		Node.PRE_DUAL_VARIABLE = "PRE-"+this.getProblemDriver().getDualVariableLabel();
		Node.UNKNOWN_DUAL_VARIABLE = "UNKNOWN-"+this.getProblemDriver().getDualVariableLabel();
    }
    
	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#init()
	 */
	public void init() {
		this.initKeys();
		ListIterator i = elements.listIterator();
		while (i.hasNext()) {
			Element elem = (Element)i.next();
			elem.init();
		}
	}

	/* (non-Javadoc)
	 * @see br.ufmg.dees.insane.model.femModel.Model#clean()
	 */
	public void clean() {
	}
    
}
